package com.pig.openg1.data;

import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.Collection;

import javax.microedition.khronos.opengles.GL;

/****
 * 球形的算法
 *  y = R * sin A ;
 *  x = ( R * cosA ) * sin B
 *  z = ( R * cosA ) * con B
 *
 * 计算圆锥
 */
public class Ball {

    private final String TAG = Ball.class.getSimpleName();

    private int mProgram,vSize;
    private FloatBuffer vertexBuffer,colorBuffer;

    private float length = 2F;
//    private float x,y,z;

    public static float[] mProjMatrix = new float[16];
    public static float[] mVMatrix = new float[16];
    public static float[] mMVPMatrix = new float[16];
    public static float[] mMMatrix = new float[16];




    public Ball(Context context) {
        //加载数据
        float[] dataPos = getData();
        vertexBuffer = getFloatBuffer(dataPos);
        vSize = dataPos.length / 3;
        //加载片元
        int verShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
        if (verShader != GLES20.GL_FALSE) {
            String verSource = loadAssert(context, "Ball_ver.glsl");
            GLES20.glShaderSource(verShader, verSource);
            GLES20.glCompileShader(verShader);
            int[] complied = new int[1];
            GLES20.glGetShaderiv(verShader, GLES20.GL_COMPILE_STATUS, complied, 0);
            if (complied[0] == GLES20.GL_FALSE) {
                Log.e(TAG, GLES20.glGetShaderInfoLog(verShader));
                GLES20.glDeleteShader(verShader);
                verShader = 0;
                Log.i(TAG,"加载顶点着色器失败！");
            }
        }
        int fragShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
        if (fragShader != GLES20.GL_FALSE) {
            String fragSource = loadAssert(context, "Ball_frag.glsl");
            GLES20.glShaderSource(fragShader, fragSource);
            GLES20.glCompileShader(fragShader);
            int[] compiled = new int[1];
            GLES20.glGetShaderiv(fragShader, GLES20.GL_COMPILE_STATUS, compiled, 0);
            if (compiled[0] == GLES20.GL_FALSE) {
                Log.e(TAG, GLES20.glGetShaderInfoLog(fragShader));
                GLES20.glDeleteShader(fragShader);
                fragShader = 0;
                Log.i(TAG,"加载片元着色器失败！");
            }
        }

        //创建着色器
        mProgram = GLES20.glCreateProgram();

        if(mProgram != 0 )
        {
            GLES20.glAttachShader(mProgram, verShader);
            GLES20.glAttachShader(mProgram, fragShader);
            //连接当前的程序
            GLES20.glLinkProgram(mProgram);
            int[] linkStatus = new int[1];
            GLES20.glGetProgramiv(mProgram,GLES20.GL_LINK_STATUS,linkStatus,0);
            if(linkStatus[0] == GLES20.GL_FALSE)
            {
                Log.e(TAG,GLES20.glGetProgramInfoLog(mProgram));
                GLES20.glDeleteProgram(mProgram);
                mProgram = 0;
            }
        }

    }

    public void drawSelf()
    {
        GLES20.glUseProgram(mProgram);
        int vMatrix =  GLES20.glGetUniformLocation(mProgram,"vMatrix");
        GLES20.glUniformMatrix4fv(vMatrix,1,false,mMVPMatrix,0);
        int vPosition = GLES20.glGetAttribLocation(mProgram,"vPosition");
        GLES20.glEnableVertexAttribArray(vPosition);

        GLES20.glVertexAttribPointer(vPosition,3,GLES20.GL_FLOAT,false,0,vertexBuffer);
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN,0,vSize);

        GLES20.glDisableVertexAttribArray(vPosition);


    }





    private int loadShader(int type,String source)
    {
        int shader = GLES20.glCreateShader(type);
        if(shader != 0 )
        {
            GLES20.glShaderSource(shader,source);
            GLES20.glCompileShader(shader);
            int[] compiled = new int[1];
            GLES20.glGetShaderiv(shader,GLES20.GL_COMPILE_STATUS,compiled,0);
            if(compiled[0] != GLES20.GL_TRUE)
            {
                Log.e(TAG,GLES20.glGetShaderInfoLog(shader));
                GLES20.glDeleteShader(shader);
                shader = 0;
            }
        }
        return shader;
    }

    private String loadAssert(Context mContext,String file)
    {
        String result = null;
        try{
            InputStream in = mContext.getAssets().open(file);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int lenght;
            byte[] buffer = new byte[1024];
            while ( (lenght = in.read(buffer))> 0 )
            {
                out.write(buffer,0,lenght);
            }
            result = out.toString();
            result = result.replaceAll("\\r\\n","\n");
            in.close();
            out.close();
        }catch(Exception e)
        {
            Log.e(TAG,e.getMessage());
            return result;
        }
        return result;
    }

    private FloatBuffer getFloatBuffer(float[] buffer) {
        ByteBuffer mByteBuffer = ByteBuffer.allocateDirect(buffer.length * 4 );
        mByteBuffer.order(ByteOrder.nativeOrder());
        FloatBuffer mFloatBuffer = mByteBuffer.asFloatBuffer();
        mFloatBuffer.put(buffer);
        mFloatBuffer.position(0);
        return mFloatBuffer;
    }

    /****
     * 球形的算法
     *  y = R * sin A ;
     *  x = ( R * cosA ) * sin B
     *  z = ( R * cosA ) * con B
     *
     * 计算圆锥
     */
    public float[] getData() {
        ArrayList<Float> list = new ArrayList<>();
        float x,y,z,x1,y1,z1;
        for(float i = -90 ; i < 90 + length; i+= length)
        {
            //y轴
            y = (float)Math.sin( i * Math.PI/ 180);
            y1 = (float)Math.sin( (i + length) * Math.PI/ 180);
            float allude = (float)Math.cos( i * Math.PI / 180);
            float allude1 = (float)Math.cos( (i + length) * Math.PI / 180);
            for(float j = 0;j< 360 + 4F;j+= 4F)
            {
                x = (float) (allude * Math.sin( j * Math.PI/180 ));
                z = (float) (allude * Math.cos( j * Math.PI/ 180 ));
                x1 = (float) (allude1 * Math.sin( j * Math.PI/180 ));
                z1 = (float) (allude1 * Math.cos( j * Math.PI/180 ));
                //若果使用一个点看结果
                list.add(x);
                list.add(y);
                list.add(z);

                list.add(x1);
                list.add(y1);
                list.add(z1);
            }
        }
        float[] data = new float[list.size()];
        for(int i=0;i< data.length;i++ )
        {
            data[i] = list.get(i);
        }
        return data;
    }
}
